package com.ruoyi.framework.interceptor;

import com.alibaba.fastjson.JSON;
import com.ruoyi.framework.web.service.SystemApiServiceImpl;
import com.ruoyi.system.api.ResponseWithData;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * API接口拦截器 验证ACCESS_TOKEN、SIGN签名
 * @date 2019/7/10 16:00
 * @author shihx
 * @return
 */
@Component
public class ApiInterceptor implements HandlerInterceptor {

    private static final Log log = LogFactory.getLog(ApiInterceptor.class);

    @Autowired
    SystemApiServiceImpl systemApiService;


    /**
     * 在请求处理之前进行调用（Controller方法调用之前）
     */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {

        log.info("url: ======"+ httpServletRequest.getRequestURI()+"===============");
        log.info("API Interceptor Start");
        /** ACCESS_TOKEN 验证标识 */
        boolean tokenFlag = false;
        /** SIGN 签名验证标识 */
        boolean signFlag = false;

        ResponseWithData returnValue = new ResponseWithData<>();

        /** 获取注解参数信息 */
        HandlerMethod handlerMethod = (HandlerMethod) object;
        Method method = handlerMethod.getMethod();
        Authentication annotation = method.getAnnotation(Authentication.class);

        if(annotation==null){
            log.error(JSON.toJSONString(returnValue.error("服务器运行时异常").code(ResponseWithData.RESULT_SERVER_ERROR)));
            httpServletResponse.setCharacterEncoding("UTF-8");
            httpServletResponse.getWriter().write(JSON.toJSONString(returnValue.error("服务器运行时异常").code(ResponseWithData.RESULT_SERVER_ERROR)));
            log.info("API Interceptor End");
            return false;
        }

        /** 如果两个参数同为false 则说明此接口不需要拦截验证 直接放行 */
        if(annotation!=null && !annotation.tokenRequired() && !annotation.signRequired()){
            tokenFlag = true;
            signFlag = true;
        }
        /** 如果 tokenRequired = true 则进行 ACCESS_TOKEN 验证 */
        if(annotation.tokenRequired()){
//            tokenFlag = true;
            tokenFlag = systemApiService.AccessTokenRequired(httpServletRequest, httpServletResponse, object);

            if(!tokenFlag){
                log.error(JSON.toJSONString(returnValue.error("AccessToken验证失败!").code(2000)));
                httpServletResponse.setCharacterEncoding("UTF-8");
                httpServletResponse.getWriter().write(JSON.toJSONString(returnValue.error("AccessToken验证失败!").code(ResponseWithData.RESULT_TOKEN_INVALID)));
                return false;
            }
        }else{
            tokenFlag = true;
        }
        /** 如果 signRequired = true 则进行 SIGN 签名验证 */
        if(annotation.signRequired()){
//            signFlag = systemApiService.SignRequired(httpServletRequest, httpServletResponse, object);
            signFlag = true;
        }else {
            signFlag = true;
        }

        if (!tokenFlag || !signFlag) {
            log.error(JSON.toJSONString(returnValue.error("权限不足,服务器禁止访问!").code(1000)));
            httpServletResponse.setCharacterEncoding("UTF-8");
            httpServletResponse.getWriter().write(JSON.toJSONString(returnValue.error("权限不足,服务器禁止访问!").code(ResponseWithData.RESULT_SIGN_INVALID)));
        }

        log.info("API Interceptor End");

        return (tokenFlag && signFlag);
    }


    /**
     * 请求处理之后进行调用，但是在视图被渲染之前（Controller方法调用之后）
     */
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    /**
     * 在整个请求结束之后被调用，也就是在DispatcherServlet 渲染了对应的视图之后执行（主要是用于进行资源清理工作）
     */
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }

}
